﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Helena.Models;
using Helena.Areas.Salidas.Models;
using Helena.Areas.Productos.Models;

namespace Helena.Areas.Entradas.Models
{
    public class LogicaEntrada:InterfazLogicaEntrada
    {
        DBContext Entrada_contexto = new DBContext();
        DBGenericQueriesUtil<Entrada> Tabla;
        DBGenericQueriesUtil<DetalleEntrada> tabla_detalle;
        DBGenericQueriesUtil<Producto> tabla_Producto;
        DBGenericQueriesUtil<DetalleProducto> tabla_Detalle_Producto;

        #region Comun

        LogicaProducto logica_producto = new LogicaProducto();
               
        public DBContext context_publico { get { return Entrada_contexto; } }

        public LogicaEntrada()
        {
            Tabla = new DBGenericQueriesUtil<Entrada>(Entrada_contexto, Entrada_contexto.t_Entrada);
            tabla_detalle = new DBGenericQueriesUtil<DetalleEntrada>(Entrada_contexto, Entrada_contexto.t_DetalleEntrada);
            tabla_Producto = new DBGenericQueriesUtil<Producto>(Entrada_contexto, Entrada_contexto.t_Productos);
            tabla_Detalle_Producto = new DBGenericQueriesUtil<DetalleProducto>(Entrada_contexto, Entrada_contexto.t_DetalleProductos);
        }

        public void i_AgregarEntrada(EntradaView entrada)
        {
            Tabla.agregarElemento(entrada.deserializa(this));
        }

        public void i_ModificarEntrada(EntradaView entrada)
        {
            Entrada e = entrada.deserializa(this);
            Tabla.modificarElemento(e, e.ID);
        }

        public void i_EliminarEntrada(int id)
        {
            Tabla.eliminarElemento_logico(id);
        }

        public List<EntradaView> i_RetornarEntradas()
        {
            List<Entrada> e = Tabla.retornarTodos();
            List<EntradaView> e_v = new List<EntradaView>();

            foreach (Entrada entrada in e)
                    e_v.Add(new EntradaView(entrada));
            return e_v;
        }

        public EntradaView i_RetornarEntrada(int id)
        {
            try
            {
                Entrada e = Tabla.retornarUnSoloElemento(id);
                EntradaView e_v = new EntradaView(e);
                return e_v;
            }
            catch
            {
                return null;
            }
        }

        #endregion

        #region Detalles

        public List<DetalleEntradaView> DetallesDeUnaEntrada(int entradaID)
        {
            IEnumerable<DetalleEntrada> antes = from detalles in tabla_detalle.retornarTodos()
                                               where detalles.EntradaID == entradaID && detalles.Estado == true
                                               select detalles;

            List<DetalleEntrada> detallesDeUnaEntrada = antes.ToList();
            List<DetalleEntradaView> salida = new List<DetalleEntradaView>();

            foreach (DetalleEntrada uno in detallesDeUnaEntrada)
                if (uno.Estado)
                {
                    DetalleEntradaView temp = new DetalleEntradaView(uno);
                    salida.Add(temp);
                }
            return salida;
        }
        
        public void AgregarDetalleaEntrada(int id, DetalleEntradaView dev)
        {
            bool pertenece = false;
            List<DetalleEntrada> detalles = tabla_detalle.retornarTodos()
                                           .Where(e => e.EntradaID == id)
                                           .Where(e=>e.Estado==true)
                                           .ToList();

            foreach (DetalleEntrada d in detalles)
            {
                if (d.ProductoID == dev.ProductoID)
                {
                    pertenece = true;
                }
            }

            if (pertenece == false)
            {
                tabla_detalle.agregarElemento(dev.deserializa(this));
            }

            
            //***********Suma a la tabla productos****************
            List<DetalleProducto> subproducto = tabla_Detalle_Producto.retornarTodos().Where(d => d.ProductoCID == dev.ProductoID).ToList();
            Producto producto = null;

            if (subproducto.Count == 0)
            {
                producto = tabla_Producto.retornarUnSoloElemento(dev.ProductoID);
                producto.cantidad = producto.cantidad + dev.Cantidad;
                producto.preciofabrica = dev.PrecioU;
                tabla_Producto.modificarElemento(producto, producto.ID);
            }
            else
            {
                foreach (DetalleProducto dp in subproducto)
                {
                    producto = tabla_Producto.retornarUnSoloElemento(dp.ProductoID);
                    producto.cantidad = producto.cantidad + dev.Cantidad*dp.Cantidad;
                    tabla_Producto.modificarElemento(producto, producto.ID);
                }

                producto = tabla_Producto.retornarUnSoloElemento(dev.ProductoID);
                producto.cantidad = producto.cantidad + dev.Cantidad;
                producto.preciofabrica = dev.PrecioU;
                tabla_Producto.modificarElemento(producto, producto.ID);
            }            
            //*****************************************************

        }

        public void i_ModificarDetalle(int id, DetalleEntradaView dsv)
        {
            //no se puede modificar un detalle xq se altera el stock del producto
            //y no se sabe cuanto era inicialmente
        }

        public void i_EliminarDetalle(int id, DetalleEntradaView dsv)
        {
            tabla_detalle.eliminarElemento_logico(dsv.ID);

            //***********Resta a la tabla productos****************
            List<DetalleProducto> subproducto = tabla_Detalle_Producto.retornarTodos().Where(d => d.ProductoCID == dsv.ProductoID).ToList();
            Producto producto = null;

            if (subproducto.Count == 0)
            {
                producto = tabla_Producto.retornarUnSoloElemento(dsv.ProductoID);
                producto.cantidad = producto.cantidad - dsv.Cantidad;
                producto.preciofabrica = dsv.PrecioU;
                tabla_Producto.modificarElemento(producto, producto.ID);
            }
            else
            {
                foreach (DetalleProducto dp in subproducto)
                {
                    producto = tabla_Producto.retornarUnSoloElemento(dp.ProductoID);
                    producto.cantidad = producto.cantidad - dsv.Cantidad * dp.Cantidad;
                    tabla_Producto.modificarElemento(producto, producto.ID);
                }

                producto = tabla_Producto.retornarUnSoloElemento(dsv.ProductoID);
                producto.cantidad = producto.cantidad - dsv.Cantidad;
                producto.preciofabrica = dsv.PrecioU;
                tabla_Producto.modificarElemento(producto, producto.ID);
            }         
            //*****************************************************
        }

        #endregion
    }
}
